package com.example.kotlin.utils

import android.app.Activity
import android.content.Context
import android.net.ConnectivityManager
import android.net.NetworkInfo
import android.view.View
import com.example.kotlin.annotation.BindViewTarget
import com.example.kotlin.aspect.CheckNet
import com.example.kotlin.showToast
import java.lang.reflect.Method

/**
 * @ClassName: ViewUtil
 * @Description: java类作用描述
 * @Author: chenmengjia
 * @Date: 2022/2/6 10:04
 */
object ViewUtil {


    fun inject(activity: Activity) {
        // 1.获取所有的属性
        val fields = activity.javaClass.declaredFields
        // 2.过滤关于 ViewById 属性
        for (field in fields) {
            val viewById = field.getAnnotation(BindViewTarget::class.java)
            if (viewById != null) {
                // 3.findViewById
                val view = activity.findViewById<View>(viewById.getValue)
                // 4.反射注入
                field.isAccessible = true
                try {
                    // activity 属性所在类，view 代表的是属性的值
                    field[activity] = view
                } catch (e: IllegalAccessException) {
                    e.printStackTrace()
                }
            }
        }
    }

    fun isNetworkAvailable(context: Context): Boolean {
        // 获取手机所有连接管理对象（包括对wi-fi,net等连接的管理）
        val connectivityManager =
            context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        if (connectivityManager != null) {
            // 获取NetworkInfo对象
            val networkInfo = connectivityManager.allNetworkInfo
            if (networkInfo != null && networkInfo.size > 0) {
                for (i in networkInfo.indices) {
                    // 判断当前网络状态是否为连接状态
                    if (networkInfo[i].state == NetworkInfo.State.CONNECTED) {
                        return true
                    }
                }
            }
        }
        return false
    }

    fun checkNetwork(activity: Activity) {
        // 1.获取所有的属性
        val methods = activity.javaClass.declaredMethods
        // 2.过滤关于 ViewById 属性
        for (method in methods) {
            val checkNet = method.getAnnotation(CheckNet::class.java)
            if (checkNet != null) {
                // 3.findViewById
                // val view = activity.findViewById<View>(viewById.getValue)
                // 4.反射注入
                method.isAccessible = true


                try {
                    // activity 属性所在类，view 代表的是属性的值
                    // field[activity] = view
                    val networkAvailable = isNetworkAvailable(activity)
                    if (networkAvailable) {
                        method.invoke(activity)
                    } else {
                        activity.showToast("网络不可用")
                    }
                } catch (e: IllegalAccessException) {
                    e.printStackTrace()
                }
            }
        }
    }


    private fun injectEvent(viewFinder: ViewFinder, `object`: Any) {
        // 1.获取所有方法
        val clazz: Class<*> = `object`.javaClass
        val methods: Array<Method> = clazz.declaredMethods
        // 2.获取方法上面的所有id
        for (method in methods) {
            val onClick: OnClick = method.getAnnotation(OnClick::class.java)
            if (onClick != null) {
                val viewIds: IntArray = onClick.value
                if (viewIds.size > 0) {
                    for (viewId in viewIds) {
                        // 3.遍历所有的id 先findViewById然后 setOnClickListener
                        val view = viewFinder.findViewById(viewId)
                        view?.setOnClickListener(DeclaredOnClickListener(method, `object`))
                    }
                }
            }
        }
    }
    private class DeclaredOnClickListener(
        private val mMethod: Method,
        private val mHandlerType: Any
    ) :
        View.OnClickListener {
        override fun onClick(v: View) {
            // 4.反射执行方法
            mMethod.isAccessible = true
            try {
                mMethod.invoke(mHandlerType, v)
            } catch (e: Exception) {
                e.printStackTrace()
                try {
                    mMethod.invoke(mHandlerType, null)
                } catch (e1: Exception) {
                    e1.printStackTrace()
                }
            }
        }
    }
}